package com.booter.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hbase.util.Bytes;

import java.math.BigDecimal;

@Slf4j
public class HbaseSerialize {

    private static ObjectMapper mapper = new ObjectMapper();

    private static String toJson(Object o) {
        if (o == null) {
            return "";
        }
        try {
            return mapper.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            log.error("To json error", e);
        }
        return "";
    }

    private static <T> T json2Bean(String json, Class<T> beanClass) {
        try {
            return mapper.readValue(json, beanClass);
        } catch (Exception ex) {
            log.error("to map error", ex);
            return null;
        }

    }

    public static ValueMeta serialize(Object object) {
//        if (object == null) {
//            return new byte[0];
//        }
        if (object instanceof String) {
            return new ValueMeta(String.class, Bytes.toBytes((String) object));
        }
        if (object instanceof Boolean) {
//            return Bytes.toBytes((Boolean) object);
            return new ValueMeta(Boolean.class, Bytes.toBytes((Boolean) object));
        }
        if (object instanceof Integer) {
//            return Bytes.toBytes((Integer) object);
            return new ValueMeta(Integer.class, Bytes.toBytes((Integer) object));
        }
        if (object instanceof Double) {
//            return Bytes.toBytes((Double) object);
            return new ValueMeta(Double.class, Bytes.toBytes((Double) object));
        }
        if (object instanceof Float) {
//            return Bytes.toBytes((Float) object);
            return new ValueMeta(Float.class, Bytes.toBytes((Float) object));
        }
        if (object instanceof Long) {
//            return Bytes.toBytes((Long) object);
            return new ValueMeta(Long.class, Bytes.toBytes((Long) object));
        }
        if (object instanceof Short) {
//            return Bytes.toBytes((Short) object);
            return new ValueMeta(Short.class, Bytes.toBytes((Short) object));
        }
        if (object instanceof BigDecimal) {
//            return Bytes.toBytes((BigDecimal) object);
            return new ValueMeta(BigDecimal.class, Bytes.toBytes((BigDecimal) object));
        }
        if (object instanceof Enum) {//NOPMD
            Enum<?> enu = (Enum<?>) object;
//            return Bytes.toBytes(enu.name());
            return new ValueMeta(enu.getClass(), Bytes.toBytes(enu.name()));
        }
//        return Bytes.toBytes(toJson(object));
        return new ValueMeta(object.getClass(), Bytes.toBytes(toJson(object)));
    }

    public static Object deserialize(byte[] bytes, Class<?> clazz) {
        String name = clazz.getName();
        switch (name) {
            case "java.lang.String":
                return Bytes.toString(bytes);
            case "boolean":
            case "java.lang.Boolean":
                return Bytes.toBoolean(bytes);
            case "int":
            case "java.lang.Integer":
                return Bytes.toInt(bytes);
            case "double":
            case "java.lang.Double":
                return Bytes.toDouble(bytes);
            case "float":
            case "java.lang.Float":
                return Bytes.toFloat(bytes);
            case "long":
            case "java.lang.Long":
                return Bytes.toLong(bytes);
            case "short":
            case "java.lang.Short":
                return Bytes.toShort(bytes);
            case "java.math.BigDecimal":
                return Bytes.toBigDecimal(bytes);
            default:
        }
        //直接转字符串，不再进行枚举映射
        if (clazz.isEnum()) {
            return Bytes.toString(bytes);
        }
        String s = Bytes.toString(bytes);
        return json2Bean(s, clazz);
    }


}
